home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / applications / wp / hwgpostbeta6.lha / HWGPOST / hwgpostlib.doc < prev    next >
Encoding:
Text File  |  1994-12-02  |  22.1 KB  |  548 lines

  1. PostScript shared library interface (post.library, with HWGPOST >= V22.26)
  2. ==========================================================================
  3.  
  4. HWGPOST, Copyright 1993, 1994 Heinz Wrobel, is mostly calling
  5. compatible to Post V1.7, Copyright Adrian Aylward 1991, 1992. But it
  6. is a very different beast inside.
  7.  
  8. This document is derived from Adrian Aylward's post.library
  9. documentation. It contains many comments on HWGPOST, developers should
  10. read, especially those developers who are familiar with the old
  11. post.library 1.7.
  12.  
  13.  
  14. Introduction
  15. ============
  16.  
  17. The file "post.library" is an AmigaOS Exec shared library containing a
  18. mostly Level II compliant PostScript interpreter. It is designed to
  19. be shareable between different processes, supporting arbitrarily many
  20. PostScript activations - at least until you run out of memory.
  21.  
  22. This file should be read in conjunction with the header file
  23. "postlib.h".
  24.  
  25. The standard user interface source files are distributed with the old
  26. Post 1.7. Read them as examples for now. If there is different
  27. information in this document or the current headerfile postlib.h or
  28. init.ps, the current information holds.
  29.  
  30.  
  31. Activation Records
  32. ==================
  33.  
  34. Simultaneous multiple activations of PostScript are allowed.  Before
  35. using post.library you must first open it by a call to OpenLibrary().
  36. To create an activation you then call PScreateact() which returns a
  37. pointer to the activation record.  You can then make calls to the
  38. interpreter library, passing the activation record pointer as an
  39. argument.  You can create several activations, possibly from different
  40. processes and intermingle the interpreter calls if you wish. But you
  41. CANNOT PASS ACTIVATION RECORDS BETWEEN PROCESSES! When you have
  42. finished with an activation, call PSdeleteact() to delete it and free
  43. the memory it used. Do not free bitmap memory or filehandles before
  44. freeing the activation record! When you have finished with the library
  45. call CloseLibrary(); if no other processes have it open, then Exec can
  46. remove it from memory if the space is needed.
  47.  
  48. N.B. the library can only be called from a process, as it calls
  49. various AmigaDOS functions.  IT IS NOT PERMISSIBLE TO PASS ACTIVATION
  50. RECORDS BETWEEN PROCESSES! NOTE THIS WELL!
  51.  
  52.  
  53. The Parameter Block
  54. ===================
  55.  
  56. The parameter block is the argument to PScreateact().  It specifies
  57. the addresses of the bitmap planes, size of the page, and the amount
  58. of memory to be allocated for the activation etc ...  Its format is
  59. defined in detail in the header file postlib.h.
  60.  
  61. N.B. all ints are 32 bits, shorts are 16 bits.
  62.  
  63. The page size is limited to 30000 pixels a side.  The densities
  64. (pixels per inch) may be any strictly positive integer value.  The y
  65. direction may be set to +1 - if the bitmap rows are in PostScript
  66. order (bottom row first) or -1 - Amiga order (top row first).
  67.  
  68.     page.buf[24]        Bitplane pointers, up to 24
  69.     page.len            Size in bytes of each plane
  70.     page.depth          Number plane pointers to use
  71.     page.flags          Special device options
  72.     page.bitspercolor   How many plane pointers to be used per gun.
  73.     page.PSextdevice    An optional extension to the device information
  74.     page.xbytes         Number of bytes in each row
  75.     page.xsize          Number of pixels in each row
  76.     page.ysize          Number of rows
  77.     page.ybase          Base of current band
  78.     page.yheight        Total height of full page, for band rendering
  79.     page.xden           X density
  80.     page.yden           Y density
  81.     page.ydir           Y direction
  82.  
  83. To specify how many bitplanes are used per color, you set
  84. "bitspercolor" to the appropriate value. If this value is not set, one
  85. bitplane per color is assumed and only 1, 3, and 4 are permissible as
  86. depth in this case. Example: RGB 3:3:2 => depth=8, bitspercolor=3.
  87.  
  88. Note that bitspercolor should not exceed 8.
  89.  
  90. For special use, the page device description can be enhanced by
  91. setting page.PSextdevice. The PSextdevice structure contains the
  92. following fields.
  93.  
  94.     flags               Extension of the main flags field.
  95.  
  96.     maskbuf             If set, must be a plane as in page.buf. For
  97.                         any rendering you'll get bits set in this mask
  98.                         plane. This gives you a mask of the actually
  99.                         used places in the buffer. The mask might be
  100.                         useful for BltMaskBitMapRastPort() or some
  101.                         such. erasepage will clear this mask plane.
  102.  
  103.     Kbuf[8]             Eight additional plane pointers to allow for
  104.                         true eight bit CMYK rendering. You need to set
  105.                         the depth to a value greater 24 for these to
  106.                         be used.
  107.  
  108. The length of these structures is subject to change. Always set unused
  109. fields to zero.
  110.  
  111. As a starting point for memory sizes try the values following.  (These
  112. are defined in the header file.)  For normal PostScript programs the
  113. defaults are perfectly satisfactory.  If you specify a value of zero
  114. the default will be used instead; values less than the minimum will be
  115. increased.
  116.  
  117.     memvlen     50000   VM
  118.     memflen     60000   Font cache
  119.     memllen     15000   Path lines
  120.     memhlen     20000   Halftones
  121.     memplen     60000   Pattern cache
  122.  
  123. The user data pointer is intended to be used to identify multiple
  124. activations.  You can set it to any value you like.  The function
  125. pointers are described below.
  126.  
  127.     userdata            User data pointer
  128.     flushfunc           Flush page function pointer
  129.     copyfunc            Copy page function pointer
  130.  
  131. The standard input and output streams are the AmigaDOS file handles to
  132. be used by the interpreter for %stdin, %stdout, %stderr.  Also the
  133. standard output is used for prompts and the error output for error
  134. messages. These file handles will not be closed by the interpreter
  135. even though PostScript file objects referring to them may be closed.
  136. You should not set them to NULL. If you don't need any input or
  137. output, set up valid NIL: filehandles!
  138.  
  139.     infh                Standard Input file handle
  140.     outfh               Standard Output file handle
  141.     errfh               Standard Error file handle
  142.  
  143. These are for backwards compatibility with the infamous "callextfunc"
  144. operator. You'll find details below.
  145.  
  146.     funcmax             Number of external functions
  147.     functab             Pointer to external function table, or zero
  148.  
  149. Anything else in the block is reserved and must be set to zero.
  150.  
  151.  
  152. Notes on the special device flags
  153. ---------------------------------
  154.  
  155. In the header file "postlib.h" you will find some flag definitions for
  156. the main flag field of the parameter page. They need more explanation.
  157.  
  158.     HWGPOST_DEVx_NOSHADE
  159.  
  160.         Halftoning is in effect suppressed. No halftone screens will
  161.         be used. Any color intensity that would cause shading will be
  162.         rendered as the next lower color value truly representable
  163.         within the bitplanes would. Shading is simply turned off.
  164.  
  165.     HWGPOST_DEVx_CMYK
  166.  
  167.         Old post.library supported the CMYK color space and operators.
  168.         When converting any colors to values passed to the transfer
  169.         functions, it creates RGBW values, though, instead of CMYK.
  170.         With this flag set, the colorspace mapping algorithm will stay
  171.         with CMYK and CMYK will be passed to the transfer functions if
  172.         applicable.
  173.  
  174.     HWGPOST_DEVx_INVERTOUTPUT
  175.  
  176.         The output of the transfer functions represent the value that
  177.         should be rendered into the bitplanes. With this flag set,
  178.         these values in the range [0.0;1.0] will effectively reversed
  179.         with a simple "shade = 1.0 - shade" before the rendering is
  180.         set up. This is the easiest way to create "negative" output
  181.         and might come in handy for multiple bitplane color handling,
  182.         where black should be "all bits 0" instead of "all bits 1" in
  183.         the planes. This is good for true color rendering.
  184.  
  185.  
  186. Function Pointers
  187. =================
  188.  
  189. There are two function pointers within the parameter block, which are
  190. used when the interpreter needs to call routines supplied by its
  191. client. If the pointers are zero, the calls are skipped.
  192.  
  193. To help identify calls from multiple activations, the activation
  194. record address is also passed in A0 and the userdata pointer in A1.
  195.  
  196.       flushfunc(D0: int y1, D1: int y2)
  197.  
  198. Flush the bitmap to the screen.  The interpreter calls this function
  199. after a painting operation has updated the bitmap.  Then if the output
  200. is being viewed interactively the client can update the screen or
  201. window.  The arguments are the range of bitmap rows (y1 ... y2-1) that
  202. may have been updated.
  203.  
  204.       copyfunc(D0: int num)
  205.  
  206. Copy the page to the output device.  The argument is the value of
  207. "#copies", which should be taken into account if the output is to a
  208. printer, but is not meaningful for screen output. You shoud take a
  209. look at the description for PSsignalint() below, too.
  210.  
  211.  
  212. Calling External Functions
  213. ==========================
  214.  
  215. The original "callextfunc" operator of post.library <= V1.7 is no
  216. longer supported even though it is still available in disguise as
  217. "@callextfunc". Use of this operator is strongly discouraged as it
  218. might lure you into making assumptions about internal HWGPOST data
  219. representations.
  220.  
  221. A more general way to call external functions has been devised via the
  222. new "@calluserhook" operator. This operator collects the arguments,
  223. passes them to a "Hook" as defined by the utility.library, records any
  224. changes and returns the result. This is the calling sequence:
  225.  
  226.     mark <args..> <userhookadr> <msgadr> @calluserhook
  227.  
  228. On return the operand stack will look like this:
  229.  
  230.     mark <args..> <resint>
  231.  
  232. A number from zero to eight arguments is supported. Only certain
  233. PostScript objects may be passed as arguments: integers, reals, and
  234. booleans are passed as the 32 bit bitpatterns corresponding to their
  235. values; strings are passed as the 32 bit address of their contents
  236. with the length as the following 32 bit integer. (N.B. PostScript
  237. strings are terminated by length; there is no terminating null unless
  238. the program puts one there. The user function may not go beyond the
  239. string length!)
  240.  
  241. <hookadr> and <msgadr> are integers that are used as 32 bit memory
  242. address. If no <msgadr> is needed, just use 0. These addresses should
  243. be passed to the interpreter via the PSintstring() function in full
  244. PostScript notation like "/hookadr 16#780ab44 def" to be used by
  245. special PostScript code. It is advisable to put them into special,
  246. private dictionaries.
  247.  
  248. The argument values passed are put into an array of 32 bit values
  249. which is passed as "objectptr" to the Hook. The return value will be
  250. put on the operand stack as <resint> and any changes to numeric values
  251. in the 32 bit array will be put back into the args on the operand
  252. stack. The Hook may change string contents within the address and
  253. length passed to it.
  254.  
  255. As an example assume this calling sequence:
  256.  
  257.     mark 1 string1 2.5 4 string2 false hookadr 0 @calluserhook
  258.  
  259. The 32 bit array passed to the hook as object will have these
  260. contents:
  261.  
  262.     array[0]:   32 int 1
  263.     array[1]:   string1: address
  264.     array[2]:   string1: length
  265.     array[3]:   IEEE float 2.5
  266.     array[4]:   32 int 4
  267.     array[5]:   string2: address
  268.     array[6]:   string2: length
  269.     array[7]:   0
  270.  
  271. If the hook function changes array[0] to 3, array[7] to 1, and returns
  272. -1, the resulting operand stack will contain these values:
  273.  
  274.     mark 3 string1 2.5 4 string2 true -1
  275.  
  276. Changing a string address or length should not be tried. If results
  277. are not needed, a cleartomark will get rid of them easily.
  278.  
  279. There should not be any assumptions made about internal representation
  280. of objects. For booleans, only 0 and 1 should be used.
  281.  
  282. N.B. PSintstring() is not guaranteed to work recursively. So calling
  283. it from the hook is not a good idea. The Hook is called on the
  284. interpreters context. If a local near data section is needed, the Hook
  285. function is responsible for setting up A4, e.g. from hook->h_Data.
  286. Standard rules for saving registers apply. Do not assume that A4
  287. contains anything useful!
  288.  
  289.  
  290. Calling External Functions with @callextfunc
  291. ============================================
  292.  
  293. The original "callextfunc" operator of post.library <= V1.7 is no
  294. longer supported even though it is still available in disguise as
  295. "@callextfunc". Use of this operator is strongly discouraged as it
  296. might lure you into making assumptions about internal HWGPOST data
  297. representations. It is only here for limited backwards compatibility.
  298. Do not use it for new SW!
  299.  
  300. If you supply an external function table your PostScript program can
  301. call the functions within it by the "@callextfunc" operator.  The
  302. contents of the table are the addresses of the function entry points.
  303. The functions must have standard (Lattice, non-registerised) C
  304. compatible calling sequences. They must not assume any useful value in
  305. register A4 on entry, and must preserve A4 and the other C registers
  306. on exit.
  307.  
  308. Unlike with post.library <= 1.7 there is additional information given,
  309. though. To help identify calls from multiple activations, the activation
  310. record address is also passed in A0 and the userdata pointer in A1.
  311.  
  312. Only certain PostScript objects may be passed as arguments: integers
  313. reals and booleans are passed as the 32 bit bitpatterns corresponding
  314. to their values; arrays and strings are passed as the 32 bit address
  315. of their contents - if the length is required it must be passed
  316. separately.  (N.B. PostScript strings are terminated by length; there
  317. is no terminating null unless the program puts one there.)
  318.  
  319. It is theoretically possible to pass arbitrary objects by including
  320. them within an array, but then you would need to know their PostScript
  321. representation. As the representation has been changed thoroughly for
  322. HWGPOST and will continue to change in the future, this "feature" is
  323. of no use at all!
  324.  
  325. The "@callextfunc" operator is only inserted into the system
  326. dictionary if a function table is present.  So you will not find it if
  327. you attempt to execute it from the standard user interface.
  328.  
  329.  
  330. Library Entry points
  331. ====================
  332.  
  333. Prototypes and pragmas for the entry points are defined in the header
  334. file.
  335.  
  336.  
  337.   Create a PostScript activation
  338.   ------------------------------
  339.  
  340.           D0:int arec = PScreateact(A1:struct PSparm *parm)
  341.  
  342. The result is the address of the new activation record.  If the
  343. activation fails an error code is returned instead - zero if the
  344. interpreter failed to start at all because there was insufficient free
  345. memory, or an interpreter error code if there was an error during
  346. initialisation. Otherwise the result is the address of the activation
  347. record.  The result is always returned as an int.  If is is greater
  348. than errmax then the activation was successful, and the value is an
  349. address; otherwise the activation failed, and the result is zero or an
  350. error code.
  351.  
  352.  
  353.   Delete a PostScript activation
  354.   ------------------------------
  355.  
  356.           VOID PSdeleteact(A0:APTR arec)
  357.  
  358. The activation record is deleted and the associated memory is freed.
  359.  
  360.  
  361.   Interpret a string or file
  362.   --------------------------
  363.  
  364.           D0:int errnum = PSintstring(A0:APTR arec, A1:char *string,
  365.                                       D0:int length, D1:int flags)
  366.  
  367.  
  368.   Flag bits:
  369.  
  370.     PSFLAGSTRING, PSFLAGGFILE
  371.  
  372.         If PSFLAGSTRING is set, the contents of the string are
  373.         interpreted as PostScript source.  If the flag PSFLAGFILE is
  374.         set, the string is a file name. Then the file's contents are
  375.         interpreted. If neither of these flag bits are set the string
  376.         is ignored, but the other flag bits still have their effects;
  377.         if both are set the result is undefined.
  378.  
  379.  
  380.     PSFLAGINTER
  381.  
  382.         If PSFLAGINTER is set (when interpreting a file), the file is
  383.         considered to be interactive.  The banner is printed, and the
  384.         interpreter prompts for each line of input from the file.
  385.  
  386.  
  387.     PSFLAGCLEAR
  388.  
  389.         If PSFLAGCLEAR is set, then after interpretation the operand
  390.         stack is cleared and the dictionary stack is popped until only
  391.         the system and user dictionaries remain. The execution stack
  392.         is emptied, too.
  393.  
  394.  
  395.     PSFLAGSAVE
  396.  
  397.         If PSFLAGSAVE is set, job server behaviour is set up for the
  398.         current job only. It is functionally equivalent to
  399.         (PSFLAGSTARTJOBSERVER| PSFLAGENDJOBSERVER) but you shouldn't
  400.         use the job server flags instead if you really want
  401.         PSFLAGSAVE.
  402.  
  403.         IMPORTANT: For running setup files like "init.ps", you should
  404.                    not use PSFLAGSAVE or job server flags!
  405.  
  406.  
  407.  
  408.     PSFLAGSTARTJOBSERVER, PSFLAGENDJOBSERVER
  409.  
  410.         With PSFLAGSTARTJOBSERVER and PSFLAGENDJOBSERVER one can
  411.         create one job server run, spanning multiple invocations of
  412.         PSintstring(). The former forces a successful startjob with a
  413.         "false" operand before running the job, the latter forces a
  414.         successful startjob with a "true" operand after running the
  415.         job and clears out the execution stack and does some other
  416.         private things. These flags do not nest. If you think about
  417.         using them in a tricky way: Think again and ask _first_.
  418.  
  419.         IMPORTANT: For running setup files like "init.ps", you should
  420.                    not use PSFLAGSAVE or job server flags!
  421.  
  422.  
  423.     PSFLAGERASE
  424.  
  425.         If PSFLAGERASE is set, then the page is erased.  This happens
  426.         right at the end, after any vm restore, so the page is erased
  427.         taking into account the restored transfer function(s).
  428.  
  429.  
  430. This routine is NOT guaranteed to recurse correctly; strange things or
  431. crashes may happen if you try to call it from an external function
  432. called from the same activation.
  433.  
  434.  
  435.   Signal an interrupt
  436.   -------------------
  437.  
  438.           VOID PSsignalint(A0:APTR arec, D0:int flag)
  439.  
  440. This routine may be called to set an interrupt signal flag to notify
  441. the interpreter of a special condition. The possible flag values are
  442. defined in the header file postlib.h. You may or multiple bit flags
  443. together. The interpreter tests these flags at the head of its main
  444. loop, and also within certain potentially length operators (=, ==,
  445. stack and pstack). If a flag is set it the interpreter will take
  446. appropriate action immediately and automatically clear the
  447. corresponding flag bit. You may safely call this routine at any time
  448. during the life of the activation. It is intended to be called from
  449. within your task's exception handler, if the CTRL-C break signal is
  450. set. Unlike with post.library <= V1.7 it is not possible to clear a
  451. flag once it has been set by calling this function. Only the
  452. interpreter will clear a flag bit when it is handled.
  453.  
  454. You may also call this function from the copypage callback with the
  455. PSINTSIGF_KILL flag. This will make the interpreter skip the erasepage
  456. command when doing a showpage, and allows you to obtain a generated
  457. bitmap easily. You don't need a backup bitmap then. It is advisable of
  458. course not to use PSFLAGERASE either in this case.
  459.  
  460.  
  461.   Signal a floating point error
  462.   -----------------------------
  463.  
  464.           VOID PSsignalfpe(A0:APTR arec)
  465.  
  466. This routine is intended to be called whenever a floating point trap
  467. is generated by the interpreter.  It generates an immediate
  468. undefinedresult error.  You must not call it at any other time; if you
  469. do you will crash the machine.  It is only useful if you are using the
  470. version of the library compiled for the 68881 FPU or compatible chips.
  471. (The software floating point routines do not generate traps).  Before
  472. calling the library you should set up a trap handler and set the bits
  473. in the fpcr register to enable the traps.  (If you do not set up the
  474. traps, the FPU will substitute the special value not-a-number for the
  475. result and continue.  The undefinedresult error will not be triggered,
  476. and results of your program may be incorrect.)  If you application
  477. does not use the FPU you can simply direct all traps to the library,
  478. otherwise it is essential that you ensure that you only call this
  479. routine if the trap derived from the library and not your own code.
  480.  
  481.  
  482.   Error
  483.   -----
  484.  
  485.           VOID PSerror(A0:APTR arec, D0:int errnum)
  486.  
  487. This routine is intended to be called from within your own flush or
  488. copy page functions, to signal that an error ocurred.  You can also
  489. call it from an external function.  You must not call it at any other
  490. time; if you do, you will crash the machine.  It calls the PostScript
  491. error handler and never returns.  The values for the error number are
  492. defined in the header file.
  493.  
  494.  
  495.   Return a text string corresponding to an error name
  496.   ---------------------------------------------------
  497.  
  498.           D0:const char *str = PSerrstr(A0:int arec, D0:int errnum)
  499.  
  500. Converts a postscript error number to a text string.  Returns NULL if
  501. the number is out of range.
  502.  
  503.  
  504.   Change device page
  505.   ------------------
  506.  
  507.           VOID PSsetdevice(A0:APTR arec, A1:struct PSdevice *page)
  508.  
  509. Note: While "setpagedevice" is not currently available, the effects
  510.       caused by PSsetdevice() are _very_ likely to change in many ways
  511.       when the time comes. If you feel that you rely on effects other
  512.       than simply replacing the device page buffer and dimensions,
  513.       CONTACT ME NOW.
  514.  
  515. Changes the device page buffer and dimensions.  If the clip path is
  516. still set to its initial value (the whole page) it is changed to match
  517. the new page size; otherwise it is unchanged (and may therefore
  518. possibly exceed the new page size).  All the clip paths saved on the
  519. graphics stack are similarly changed.  The CTM at the topmost saved
  520. graphics state (the one returned to by a "grestoreall" when there are
  521. no active VM saves) is reset to match the new page size and density.
  522. Otherwise the CTM is not affected; you will likely want to execute
  523. "initmatrix" afterwards.
  524.  
  525. The interactions of this routine with the stack of saved graphics
  526. states are complex, leading to unexpected behaviour unless you
  527. understand exactly what is happening.  So it is safest to think twice
  528. about calling it and always call it when there are no save's or
  529. gsave's active, and then to reinitialise the CTM immediately.
  530. In other words: You better not use it.
  531.  
  532. This routine should not be called from within a character build,
  533. kerning, or imaging procedure.
  534.  
  535.  
  536. Problems, Comments, and Bugs
  537. ============================
  538.  
  539. You will find my complete address in the header file "postlib.h".
  540. Contact me if you have any questions or suggestions. Don't rely on
  541. empirical programming. It is a lot faster and easier to ask than
  542. wasting time with fiddling around.
  543.  
  544. Heinz Wrobel
  545. <heinz@hwg.muc.de>
  546.  
  547. *** EOT ***
  548.